<?php

require_once "guid.php";

define( 'SCHEMA_STATS_PREFIX', 'http://alandix.com/schema#');
define( 'SCHEMA_STATS_ENTITY_PREFIX', 'http://alandix.com/schema/entitiy/');

define( 'SCHEMA_STATS_DEFAULT_TARGET', 'http://api.talis.com/stores/kiyanwang-dev2');

class SchemaStats {
	static $__theSchemaStats = array();
	
	var $schemaStoreUri, $schemaCredentials;
	
	var $schemaStore, $targetStore;
	
	var $targetStoreUri;
	
	var $fail = "";
	
	function __construct($targetStoreUri=false) {
		$this->schemaStoreUri = "http://api.talis.com/stores/alandix-dev1";  // **** need to abstract, maybe through a factory
		$this->schemaCredentials = new Credentials('alandix', 'kds97gp9rt');
		$this->schemaStore = new Store($this->schemaStoreUri, $this->schemaCredentials);

		if ( ! $targetStoreUri ) $targetStoreUri= "http://api.talis.com/stores/kiyanwang-dev2";
		$this->targetStoreUri = $targetStoreUri;
		$this->targetStore = new Store($this->targetStoreUri);
	}
	function makeEntityUri() {
		return SCHEMA_STATS_ENTITY_PREFIX . generatePackedGuid();
	}
	function getTheSchemaStats($targetStoreUri=false) {
		if ( ! $targetStoreUri ) $targetStoreUri = SCHEMA_STATS_DEFAULT_TARGET;
		if ( ! array_key_exists( $targetStoreUri, self::$__theSchemaStats)  ) {
			self::$__theSchemaStats[$targetStoreUri] = new SchemaStats($targetStoreUri);
		}
		return self::$__theSchemaStats[$targetStoreUri];
	}

	function storePredicateStatistcs($predicate,$statistics) {
		$predicateUri = $this->makeEntityUri();
		$graph = new SimpleGraph();
		$graph->add_resource_triple($predicateUri, SCHEMA_STATS_PREFIX . 'store', $this->targetStoreUri);
		$graph->add_resource_triple($predicateUri, SCHEMA_STATS_PREFIX . 'predicate', $predicate);
		$graph->add_literal_triple($predicateUri, SCHEMA_STATS_PREFIX . 'distinctObjectCount', $statistics['distinctObjectCount']);
		$graph->add_literal_triple($predicateUri, SCHEMA_STATS_PREFIX . 'distinctSubjectCount', $statistics['distinctSubjectCount']);
		$graph->add_literal_triple($predicateUri, SCHEMA_STATS_PREFIX . 'tripleCount', $statistics['tripleCount']);

		$response = $this->schemaStore->get_metabox()->submit_rdfxml($graph->to_rdfxml());
		if(!$response->is_success())
		{
			echo "failed to save statistics for {$predicate}";
		}

	}

	/*
		returns empty array if no statitistics available and false if store failed
	*/
	function getStoredPredicateStatistics($predicate) {
		$sprefix = SCHEMA_STATS_PREFIX;
		$schemaStoreSparql = $this->schemaStore->get_sparql_service();
		
		$store = $this->targetStoreUri;
		
	    $storedPredicateStatsQuery = "select ?distinctObjectCount ?distinctSubjectCount ?tripleCount
	where
	{
		?puri <{$sprefix}store> <{$store}> .
		?puri <{$sprefix}predicate> <{$predicate}> .
		?puri <{$sprefix}distinctObjectCount> ?distinctObjectCount .
		?puri <{$sprefix}distinctSubjectCount> ?distinctSubjectCount .
		?puri <{$sprefix}tripleCount> ?tripleCount .
	}";
/*
	    $storedPredicateStatsQuery = "select ?distinctObjectCount ?distinctSubjectCount ?tripleCount
	where
	{
		<{$predicate}> <{$sprefix}distinctObjectCount> ?distinctObjectCount .
		<{$predicate}> <{$sprefix}distinctSubjectCount> ?distinctSubjectCount .
		<{$predicate}> <{$sprefix}tripleCount> ?tripleCount .
	}";
*/
		$response = $schemaStoreSparql->select($storedPredicateStatsQuery);
		
		//echo "getStoredPredicateStatistics:oops failed to run query:\n    " . $storedPredicateStatsQuery ."\n=====\n    " . print_r($response,true) . "\n\n";

		if($response->is_success())
		{
	        $results = $schemaStoreSparql->parse_select_results($response->body);
			if ( count($results) > 0) {
				return array( 'distinctObjectCount' => $results[0]['distinctObjectCount']['value'],
							  'distinctSubjectCount' => $results[0]['distinctSubjectCount']['value'],
							  'tripleCount' => $results[0]['tripleCount']['value'],
				);
			} else {
				return array();
			}
		}
		else
		{
			echo "getStoredPredicateStatistics:oops failed to run query:" . $response->body ."\n    " . $storedPredicateStatsQuery . "\n\n";
			return false;
		}
 	
	}

	/*
		returns empty array if no statitistics available and false if store failed
	*/
	function getRawPredicateStatistics($predicate)
	{
		$predStatQuery = "select (count(distinct ?obj) as ?distinctObjectCount) (count(distinct ?s) as ?distinctSubjectCount) (count(?s) as ?tripleCount)
		where
		{
		  ?s <{$predicate}> ?obj
		}";
	
		$targetStoreSparql = $this->targetStore->get_sparql_service();
	    $response = $targetStoreSparql->select($predStatQuery);
	    if($response->is_success())
	    {
	        $results = $targetStoreSparql->parse_select_results($response->body);
			if ( count($results) > 0) {
				return array( 'distinctObjectCount' => $results[0]['distinctObjectCount']['value'],
							  'distinctSubjectCount' => $results[0]['distinctSubjectCount']['value'],
							  'tripleCount' => $results[0]['tripleCount']['value'],
				);
			} else {
				return array();
			}
		} else {
			echo "getRawPredicateStatistics: oops failed to run query:" . $response->body ."\n";
			return false;
		}	
	}

	/*
		returns empty array if no statitistics available and false if store failed
	*/
	function getPredicateStatistics($predicate)
	{
		$statistics = $this->getStoredPredicateStatistics($predicate);
		if( $statistics!==false && !$statistics )
		{
			echo "Did not find stored predicates, retrieving Raw ...\n";
			$statistics = $this->getRawPredicateStatistics($predicate);
			if( $statistics )
			{
				echo "Saving Raw Statistics ...\n";
				$this->storePredicateStatistcs($predicate, $statistics);
			}
		}
		//echo "getPredicateStatistics($predicate): ".print_r($statistics,1)."   \n";
		return $statistics;
	}

}

?>